package org.geometerplus.zlibrary.core.filesystem.ceb;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.geometerplus.zlibrary.core.filesystem.ZLFile;

/**
 * ceb文件的wraper
 * @author zouqp
 * 2014-09-28
 */


public class CebFile
{
    private ZLFile selfFile; // ceb文件的全名
    private byte[] contents; //ceb文件的内容 
    //META-INF区内文件信息
    private List<Object[]> miFileList = new ArrayList<Object[]>();// 存储[段内id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]的列表
     // 数据区段文件引用数据获取
    private List<Object[]> dataFileList = new ArrayList<Object[]>();// 存储[区段id,文件id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]列表
    //文件大小的存储区
    private HashMap<String, Integer> fileSizes = new HashMap<String,Integer>();
    
	public CebFile(ZLFile file ) {
		this.selfFile = file;
	}
	
	public void DecompressCEBFile( ){
		CEBDecompressor decompressor  = new CEBDecompressor( );
		try{
		    decompressor.DecompressCEBPackage(selfFile.getPath(), this);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void setContents(byte[] contents ) {
		this.contents = contents;
	}
	
	public void setMiFileList(List<Object[]> fileList ) {
		miFileList = fileList;
	}
	
	public void setDataFileList(List<Object[]> fileList ) {
		dataFileList = fileList;
	}
	
	public InputStream getSubFileInputStream(String fileName ) {
		  //先查找meta info 文件
		  // [段内id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]
			//fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
			for (int i = 0; i < miFileList.size(); i++)
			{
				if (fileName.equals((String) ((Object[]) miFileList.get(i))[5]))
				{
					int fileLength = ((Integer) ((Object[]) miFileList.get(i))[4]).intValue();// 文件长度
					fileSizes.put(fileName, fileLength);
					int startPos = ((Integer) ((Object[]) miFileList.get(i))[3]).intValue();// 文件起始位置
					byte[] temp = new byte[fileLength];
					System.arraycopy(contents, startPos, temp, 0, fileLength);
					return new ByteArrayInputStream(temp);
				}
			}
		    //再查找 内容 文件
		   // [区段id,文件id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]
			for (int i = 0; i < dataFileList.size(); i++)
			{
				if (fileName.equals((String) ((Object[]) dataFileList.get(i))[6]))
				{
					int fileLength = ((Integer) ((Object[]) dataFileList.get(i))[5]).intValue();// 文件长度
					fileSizes.put(fileName, fileLength);
					int startPos = ((Integer) ((Object[]) dataFileList.get(i))[4]).intValue();// 文件起始位置
					byte[] temp = new byte[fileLength];
					System.arraycopy(contents, startPos, temp, 0, fileLength);
					return new ByteArrayInputStream(temp);
				}
			}
			return null;
	}
	
	public long getSubFileSize(String fileName) {
		long size = -1; //如果返回-1表示没有找到文件
		//fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
		Integer sizeObj = fileSizes.get(fileName);
		if(sizeObj != null ) {
			return sizeObj.longValue();
		}
		//先查找meta info 文件
		  // [段内id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]
			for (int i = 0; i < miFileList.size(); i++)
			{
				if (fileName.equals((String) ((Object[]) miFileList.get(i))[5]))
				{
					int fileLength = ((Integer) ((Object[]) miFileList.get(i))[4]).intValue();// 文件长度
					fileSizes.put(fileName, fileLength);
					return fileLength;
				}
			}
		    //再查找 内容 文件
		   // [区段id,文件id,文件是否压缩,压缩类型,文件起始位置(绝对偏移),文件长度,文件名称]
			for (int i = 0; i < dataFileList.size(); i++)
			{
				if (fileName.equals((String) ((Object[]) dataFileList.get(i))[6]))
				{
					int fileLength = ((Integer) ((Object[]) dataFileList.get(i))[5]).intValue();// 文件长度
					fileSizes.put(fileName, fileLength);
					return fileLength;
				}
			}
		return size;
	}
	
	public boolean subFileExists(String fileName){
		return getSubFileSize(fileName) != -1;
	}
	
	public List<ZLFile> getAllSubFiles() {
		List<ZLFile> allEntries = getAllMiSubFiles();
		allEntries.addAll(getAllDataSubFiles());
		return allEntries;
	}
	
    public List<ZLFile> getAllMiSubFiles() {
    	List<ZLFile> entries = new ArrayList<ZLFile>(miFileList.size());
    	for (int i = 0; i < miFileList.size(); i++)
		{
    		String fileName = (String) ((Object[]) miFileList.get(i))[5];
    		LQCebEntryFile cebFileEntry = new LQCebEntryFile(selfFile, fileName);
    		entries.add(cebFileEntry);
		}
    	return entries;
	}
    
    public List<ZLFile> getAllDataSubFiles() {
    	List<ZLFile> entries = new ArrayList<ZLFile>(dataFileList.size());
    	for (int i = 0; i < dataFileList.size(); i++)
		{
    		String fileName = (String) ((Object[]) dataFileList.get(i))[6];
    		LQCebEntryFile cebFileEntry = new LQCebEntryFile(selfFile, fileName);
    		entries.add(cebFileEntry);
		}
    	return entries;
   	}
}
